public without sharing class AboardPriceListController {
    

	public String backId {get; private set;} 
	public String msg {get; private set;} 
	public Boolean isErr {get; private set;} 
	public String dataJson {get; private set;} 
	public String saveJson {get;  set;} 
	public String searchJson {get;  set;} 
	public Boolean isSuccess {get ; private set;}
	private Boolean isNew ; 
    public class ControllerException extends Exception {}
	private  String sealflag;
	private AdjustPrice__c ap ; 
	public  String company {private set; get; }
    public  String province  {private set; get; }
	public String accountId {private set; get;}
	private Map<String,DataUtil.SObjectBean> stageObjectMap ; 

    public AboardPriceListController() {
        stageObjectMap = new Map<String,DataUtil.SObjectBean>();
    }

    public void setNil(){
    	dataJson = '{}';
    	saveJson = '[]';
    	searchJson = '{}';
    }
    //设置错误
    private void setError(String message){
    	isErr = true;
      throw new ControllerException(message);

    }

     public void init(){
    	backId = System.currentPageReference().getParameters().get('id');
    	ap = new AdjustPrice__c();
    	isNew = false; 
    	try {
    	 	if(backId == null) setError('打开页面错误!');

    	 	String oppId = null; 
    	 	if(Id.valueOf(backId).getSObjectType() == Account.SObjectType){
    	 		
    	 		ap.Account__c = backId;
    	 		ap.Company__c = '迈克生物股份有限公司';
    	 		isNew = true; 
                ap.Status__c = '草案中';
                ap.RecordTypeId = Utils.getRecordTypeIdByDevNameAndObjName('PriceAdjustmentOversea', 'AdjustPrice__c');
                province = [select PriceProvince__c from User where Id=:UserInfo.getUserId()].PriceProvince__c;

    	 	}else if(Id.valueOf(backId).getSObjectType() == AdjustPrice__c.SObjectType){
    	 		ap = [select Id,Company__c ,OwnerId ,Account__c,Reason__c,Status__c  from AdjustPrice__c where Id=:backId];
    	 		if(ap.Status__c == '已提交' || ap.Status__c == '已批准'  )setError('产品调价'+ap.Status__c +'不能修改!');
                 province = [select PriceProvince__c from User where Id=:ap.OwnerId].PriceProvince__c;
    	 	}else{
    	 		setError('打开页面错误!');
    	 	}
            if(System.Test.isRunningTest())province = null;
    	 	accountId = ap.Account__c; 
    	 	company = ap.Company__c;
    		sealflag  =  'Y-'+ ImportObject.getPicklistValues('Contract__c','Corpcode__c',false).get(company);   
             Map<String,Object>dataMap = new Map<String,Object>();

    		/* //字段
	    	 Map<String,Set<String>> fieldsmap = getFields();
	    	 //字段详情
	    	 Map<String, List<DataUtil.FieldBean>> fbMap = DataUtil.getFieldsBean(fieldsmap,stageObjectMap);
	    	//字段赋值
	    	 Map<String,List<DataUtil.FieldBean>> fields = DataUtil.setFieldsValue(fbMap,DataUtil.getBaseInfo(fbMap,stageObjectMap) );
	 		dataMap.put('base',fields);
    		dataMap.put('baseObject',DataUtil.getBaseObjectMap(stageObjectMap)); 
            */
    		dataMap.put('searchObject',getSearchObject()); 
    		dataMap.put('detail',getDetails()); 

    		dataJson = EncodingUtil.urlEncode(JSON.serialize(dataMap), 'UTF-8');


    	}catch (Exception e) {
    	    ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR ,e.getMessage()));

    	}
    	
    }

    public void search(){
    	dataJson = '[]';
    	Map<String,Object> searchMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(searchJson,'UTF-8'));

    	String sql = ' select Id ,ProductName__c ,SerialNo__c ,Model__c, Brand__c ,Spec__c,Category0__c,NCCode__c ,Category1__c ,SealCompany__c from Product__c where   Category3__c  in  ' +Label.RegentCatagory3 +' and  (Overseasproducts__c  = true  or Brand__c in '+MaccuraBrandUtil.getMaccuraInStr()+ ') ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('ProductName__c'))) == false) sql += ' and ProductName__c like \'%'+DataUtil.getStringValue(searchMap.get('ProductName__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Brand__c'))) == false) sql += ' and Brand__c like \'%'+DataUtil.getStringValue(searchMap.get('Brand__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Spec__c'))) == false) sql += ' and Spec__c like \'%'+DataUtil.getStringValue(searchMap.get('Spec__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('SerialNo__c'))) == false) sql += ' and SerialNo__c like \'%'+DataUtil.getStringValue(searchMap.get('SerialNo__c'))+'%\' ';
 
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category0__c'))) == false) sql += ' and Category0__c like \'%'+DataUtil.getStringValue(searchMap.get('Category0__c'))+'%\' ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category1__c'))) == false) sql += ' and Category1__c like \'%'+DataUtil.getStringValue(searchMap.get('Category1__c'))+'%\' ';
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('NCCode__c'))) == false) sql += ' and NCCode__c like \'%'+DataUtil.getStringValue(searchMap.get('NCCode__c'))+'%\' ';

    	sql += ' limit 200 ';
    	List<AdjustPriceBean>  tmp = new  List<AdjustPriceBean>();
    	Map<Id,Product__c > pMap  = new Map<Id,Product__c>();
        System.debug('search=>'+sql);

    	for(Product__c p: Database.query(sql)){
            if(p.SealCompany__c != null && p.SealCompany__c.contains(sealflag)) continue; 
			pMap.put(p.Id , p);
    	}

        System.debug(pMap.keySet());
        System.debug('search=>'+company);

   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pMap.keySet(), company,province);


   		Map<Id,PriceList__c> prLMap = AboardPriceListController.getPriceListMap(pMap.keySet(),ap.Account__c );

   		for(Product__c p : pMap.values()){

   			tmp.add(new AdjustPriceBean(p,prMap.get(p.Id),prLMap.get(p.Id)));
   		}
    	dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');

    }
    public void searchPriceList(){
    	dataJson = '[]';
    	Map<String,Object> searchMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(searchJson,'UTF-8'));

    	String sql = ' select Id,Product__c ,Product__r.ProductName__c ,Product__r.SerialNo__c ,Product__r.Model__c, Product__r.Brand__c ,Product__r.Spec__c,'+
    	' Product__r.Category0__c,Product__r.NCCode__c ,Product__r.Category1__c ,Product__r.SealCompany__c ,CooperativePrice__c	,BuyingPrice__c, Remarks__c,PrototypePrice__c '+
    	' from PriceList__c where  Account__c =\''+ap.Account__c+'\' ';
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('ProductName__c'))) == false) sql += ' and Product__r.ProductName__c like \'%'+DataUtil.getStringValue(searchMap.get('ProductName__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Brand__c'))) == false) sql += ' and Product__r.Brand__c like \'%'+DataUtil.getStringValue(searchMap.get('Brand__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Spec__c'))) == false) sql += ' and Product__r.Spec__c like \'%'+DataUtil.getStringValue(searchMap.get('Spec__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('SerialNo__c'))) == false) sql += ' and Product__r.SerialNo__c like \'%'+DataUtil.getStringValue(searchMap.get('SerialNo__c'))+'%\' ';
 
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category0__c'))) == false) sql += ' and Product__r.Category0__c like \'%'+DataUtil.getStringValue(searchMap.get('Category0__c'))+'%\' ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category1__c'))) == false) sql += ' and Product__r.Category1__c like \'%'+DataUtil.getStringValue(searchMap.get('Category1__c'))+'%\' ';
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('NCCode__c'))) == false) sql += ' and Product__r.NCCode__c like \'%'+DataUtil.getStringValue(searchMap.get('NCCode__c'))+'%\' ';

    	sql += ' limit 200 ';
    	List<AdjustPriceBean>  tmp = new  List<AdjustPriceBean>();
    	Map<Id,PriceList__c > pMap  = new Map<Id,PriceList__c>();
    	for(PriceList__c p: Database.query(sql)){
            if(p.Product__r.SealCompany__c != null && p.Product__r.SealCompany__c.contains(sealflag)) continue; 
			pMap.put(p.Product__c , p);
    	}
   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pMap.keySet(), company);

   		for(PriceList__c p : pMap.values()){

   			tmp.add(new AdjustPriceBean(p, prMap.get(p.Product__c )));
   		}
    	dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');

    }


   	public static Map<Id,PriceList__c> getPriceListMap (Set<Id> pset,String accId ){
   		Map<Id,PriceList__c> prLMap = new Map<Id,PriceList__c> ();

   		for(PriceList__c pl :[select Id,Product__c ,CooperativePrice__c	,BuyingPrice__c, Remarks__c,PrototypePrice__c  from PriceList__c where Product__c in: pset  and Account__c =: accId ]){  			
   			prLMap.put(pl.Product__c , pl);
   		}
   		return prLMap;

   	}

   	@RemoteAction
    public static List<AdjustPriceBean>  matchProduct(List<String> nccodes,String accId, String comp ,String province  ){
    	List<AdjustPriceBean> tmp = new List<AdjustPriceBean>();
    	Map<Id,Product__c > pMap  = new Map<Id,Product__c>();
    	String sealflag = 'Y-MKSW';
    	for(Product__c p : [select Id,ProductName__c ,SerialNo__c ,SealCompany__c,Model__c, Brand__c ,Spec__c,Category0__c,NCCode__c,Category1__c 
    	 from Product__c where NCCode__c in: nccodes and (Overseasproducts__c = true or Brand__c in: MaccuraBrandUtil.maccura) ]){
            if(p.SealCompany__c != null && p.SealCompany__c.contains(sealflag)) continue; 
			pMap.put(p.Id , p);
    	}

   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pMap.keySet(),comp,province);

   		Map<Id,PriceList__c> prLMap = getPriceListMap(pMap.keySet(),accId);
   		for(Product__c p : pMap.values()){
            if(!prMap.containsKey(p.Id))continue;
   			tmp.add(new AdjustPriceBean(p,prMap.get(p.Id),prLMap.get(p.Id)));
   		}
    	return tmp; 
    }


   /* private Map<String,Set<String>>  getFields(){
    	Map<String,Set<String>> fieldsMap  = new  Map<String,Set<String>>();
    	
    		DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

    		sb.title ='基本信息';
    		sb.objname = 'AdjustPrice__c';
    		sb.stype = DataUtil.getSObjectType('AdjustPrice__c');
    		if(!isNew)sb.idvalue = ap.Id  ;
    		sb.type = 'base';
    		sb.condition = ' where Id =\''+ap.Id+'\'';
    		stageObjectMap.put('AdjustPrice__c',sb );

    		 Set<String>  fields = new Set<String>{'Currency__c','Reason__c'};
    		fieldsMap.put('AdjustPrice__c', fields);
    	
    	return fieldsMap;

    }*/

     private Map<String,List<DataUtil.FieldBean>> getSearchObject(){
    	Map<String,List<DataUtil.FieldBean>> searchMap = new Map<String,List<DataUtil.FieldBean>>();

    	Map<String,DataUtil.FieldBean>proMap = DataUtil.getFieldsInfo(Product__c.SObjecttype, new Set<String>{'ProductName__c','Brand__c','Spec__c','SerialNo__c','Category0__c','Category1__c','NCCode__c'} );
    	searchMap.put('Product__c', proMap.values());
    	return searchMap;
    }
    public void save(){

    	msg = '';
        try {


            Map<String,Object> saveMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson, 'UTF-8'));

            if(saveMap.containsKey('base')){
                Map<String,Object> baseMap = (Map<String,Object>) saveMap.get('base');
                //if(baseMap.containsKey('Currency__c'))ap.Currency__c = DataUtil.getStringValue(baseMap.get('Currency__c'));
                if(baseMap.containsKey('Reason__c'))ap.Reason__c = DataUtil.getStringValue(baseMap.get('Reason__c'));
            }
            Set<String>  prosets = new Set<String>();


            List<AdjustPriceProduct__c>qList =new List<AdjustPriceProduct__c>();
            if(saveMap.containsKey('detail')){
                List<Object> qpList = (List<Object>)saveMap.get('detail');
                Set<Id> prdset = new Set<Id>();
                for(Object o : qpList){
                    Map<String,Object> mo = (Map<String,Object>)o ; 
                    prdset.add(Id.valueOf(DataUtil.getStringValue(mo.get('productId'))));

                }
               Map<Id,Price__c> priceMap = ImportObject.getPriceMap(prdset,company,province);

               System.debug('save=>'+JSON.serialize(priceMap));
            System.debug('save=>'+prdset);
            System.debug('save=>'+company);

                for(Object o : qpList){
                    Map<String,Object> mo = (Map<String,Object>)o ; 

                    AdjustPriceProduct__c qp= new AdjustPriceProduct__c();
                    
                    qp.Product__c = Id.valueOf(DataUtil.getStringValue(mo.get('productId')));
                    qp.PresentPrice__c = DataUtil.getDecimalValue(mo.get('coopprice'));
                    qp.OriginalCombinedPrice__c = DataUtil.getDecimalValue(mo.get('oricoopprice'));
                    qp.PurchasePriceNow__c = DataUtil.getDecimalValue(mo.get('buyprice'));
                    qp.OriginalPurchasePrice__c = DataUtil.getDecimalValue(mo.get('oribuyprice'));
                    qp.PresentRemarks__c = DataUtil.getStringValue(mo.get('note'));
                    qp.OriginalRemarks__c = DataUtil.getStringValue(mo.get('orinote'));
                    qp.SalesmanPrice__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).SalesmanPrice__c :null ;
                    qp.SalesDirectorPrice__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).SalesDirectorPrice__c :null ;
                    qp.SalesManagerPrice__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).SalesManagerPrice__c :null ;
                    qp.MarketQuotation__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).MarketPriceUSD__c :null ;

                   if(qp.MarketQuotation__c == null || qp.MarketQuotation__c == 0)prosets.add(DataUtil.getStringValue(mo.get('productName')));


                    qList.add(qp);

                }
            }
            if(!prosets.isEmpty())throw new DmlException('以下产品没有海外标准报价(美元):'+String.join(new List<String>(prosets), ','));
            if(qList.size() == 0 )throw new DmlException('没有产品数据!');
                   
            SavePoint sp = Database.setSavepoint();
            try {
               upsert ap ; 
               if(!isNew)delete [select Id from AdjustPriceProduct__c where AdjustPrice__c =:ap.Id ];
               for(AdjustPriceProduct__c qp : qList){
                    qp.AdjustPrice__c = ap.Id; 
               }
               if(qList.size() > 0) insert qList;
               isSuccess = true; 
               backId = ap.Id ; 
               msg = '保存成功!';
            }catch (Exception e) {
                Database.rollback(sp);
                
                if(isNew){
                    ap.Id  = null; 
                }
                throw e;
            }
            
        }catch (Exception e) {
            msg = '保存失败:'+e.getMessage();
        }
        
    	
    	
    }

    ////获取报价产品
    private List<AdjustPriceBean> getDetails( ){
    	List<AdjustPriceBean>  tmp = new  List<AdjustPriceBean>();
    	if(!isNew){
    		Set<Id > pset = new Set<Id >();
    		List<AdjustPriceProduct__c> qList = [select Id, Product__c , Product__r.Category1__c,Product__r.NCCode__c,
			Product__r.ProductName__c,Product__r.Category0__c,Product__r.Brand__c,Product__r.Model__c,
			Product__r.Spec__c,Product__r.SerialNo__c , PresentPrice__c ,PurchasePriceNow__c ,PresentRemarks__c ,
			OriginalPurchasePrice__c , OriginalCombinedPrice__c,OriginalRemarks__c
			 from AdjustPriceProduct__c where AdjustPrice__c =:ap.Id ];

			for(AdjustPriceProduct__c ip :qList){
				pset.add(ip.Product__c);
			}
            Map<Id,PriceList__c> prLMap = AboardPriceListController.getPriceListMap(pset,ap.Account__c );

	   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pset, company,province);
	   		for(AdjustPriceProduct__c ip :qList){
	   			tmp.add(new AdjustPriceBean(ip,prMap.get(ip.Product__c),prLMap.get(ip.Product__c)));

			}

    	}
    	return tmp ; 
    }

    public class AdjustPriceBean{
    	public String productName ;
    	public String productId ;
    	public String cate0;
    	public String cate1 ;
    	public String spec; 
    	public String serialno ;
    	public String brand ;
    	public String nccode ; 
    	public Decimal marketprice; 
    	public Decimal marketpriceCNY; 

    	public Decimal coopprice ; 
    	public Decimal cooppriceCNY; 

    	public Decimal oricoopprice ; 
    	public Decimal oricooppriceCNY;  

    	public Decimal discount ; 

    	public Decimal buyprice ; 
    	public Decimal buypriceCHY ; 
    	public Decimal oribuyprice ; 
    	public Decimal oribuypriceCHY ; 

    	public String model; 
    	public String note; 
    	public String orinote; 
        public Boolean hasprice;

    	public AdjustPriceBean(AdjustPriceProduct__c app ,Price__c pr,PriceList__c pl ){
    		productName = app.Product__r.ProductName__c;
    		productId = app.Product__c;
    		cate0 = app.Product__r.Category0__c;
    		cate1 = app.Product__r.Category1__c;
    		spec = app.Product__r.Spec__c;
    		serialno = app.Product__r.SerialNo__c;
    		brand = app.Product__r.Brand__c;
    		nccode = app.Product__r.NCCode__c;
            model = app.Product__r.Model__c;
    		if(pr != null )marketprice = pr.MarketPriceUSD__c;
    		coopprice = app.PresentPrice__c;
    		//oricoopprice = app.OriginalCombinedPrice__c;
    		buyprice = app.PurchasePriceNow__c; 
    		//oribuyprice = app.OriginalPurchasePrice__c; 
            if(pl != null )oricoopprice = pl.CooperativePrice__c;
            if(pl != null )oribuyprice = pl.BuyingPrice__c;
            if(pl != null )orinote = pl.Remarks__c;

            hasprice = pr != null; 


    		note = app.PresentRemarks__c;
    		//orinote = app.OriginalRemarks__c;

    	}

    	public AdjustPriceBean(Product__c p , Price__c pr , PriceList__c pl ){
    		productName = p.ProductName__c;
    		productId = p.Id ;
    		cate0 = p.Category0__c;
    		cate1 = p.Category1__c;
    		spec = p.Spec__c;
    		serialno = p.SerialNo__c;
    		brand = p.Brand__c;
    		nccode = p.NCCode__c;
            model = p.Model__c;
            hasprice = pr != null; 
    		if(pr != null )marketprice = pr.MarketPriceUSD__c;
    		if(pl != null )orinote = pl.Remarks__c;
            if(pl != null )note = pl.Remarks__c;

    		if(pl != null )oricoopprice = pl.CooperativePrice__c;
    		if(pl != null )oribuyprice = pl.BuyingPrice__c;
            if(pl != null )buyprice = pl.BuyingPrice__c;


    	}
    	public AdjustPriceBean(PriceList__c pl  , Price__c pr ){
    		productName = pl.Product__r.ProductName__c;
    		productId = pl.Product__c  ;
    		cate0 = pl.Product__r.Category0__c;
    		cate1 = pl.Product__r.Category1__c;
    		spec = pl.Product__r.Spec__c;
    		serialno = pl.Product__r.SerialNo__c;
    		brand = pl.Product__r.Brand__c;
    		nccode = pl.Product__r.NCCode__c;
            model = pl.Product__r.Model__c;
            hasprice = pr != null; 
    		if(pr != null )marketprice = pr.MarketPriceUSD__c;
    		orinote = pl.Remarks__c;
            note = pl.Remarks__c;
    		oricoopprice = pl.CooperativePrice__c;
    		oribuyprice = pl.BuyingPrice__c;
            buyprice = pl.BuyingPrice__c;

    	}

    }



}